package cn.rdq.common.file;


import cn.rdq.common.util.FileNameUtils;
import cn.rdq.common.util.support.FileConst;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.jws.Oneway;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Calendar;
import java.util.Locale;
import java.util.Objects;

@Component
public class LocalFileHandler {

    /**
     * 主目录
     */
    private final String workDir = FileConst.WORK_DIR;

    /**
     * 上传子目录
     */
    private final static String UPLOAD_SUB_DIR = FileConst.UPLOAD_SUB_DIR;

    /**
     * 路径分隔符
     */
    private final static String FILE_SEPARATOR = FileConst.FILE_SEPARATOR;

    public LocalFileHandler() {
        initDirectory();
        checkWorkDir();
    }

    /**
     * Check work dir
     */
    private void checkWorkDir() {
        // 获取主目录路径
        Path workPath = Paths.get(workDir);

        Assert.isTrue(Files.isDirectory(workPath), workDir + " not be a directory.");

        Assert.isTrue(Files.isReadable(workPath), workDir + " not readable.");

        Assert.isTrue(Files.isWritable(workPath), workDir + " not writable.");
    }

    /**
     * 初始化各目录
     */
    private void initDirectory() {
//        C://users/lwj/FileUploadDemo/
        Path uploadPath = Paths.get(workDir + UPLOAD_SUB_DIR);
        try {
            if (Files.notExists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }
        } catch (IOException ie) {
            throw new RuntimeException("初始化目录失败", ie);
        }
    }

    public String upload(MultipartFile file) {
        Assert.notNull(file, "文件不能为空！");

        // 获取当前时间
        Calendar current = Calendar.getInstance(Locale.SIMPLIFIED_CHINESE);

        // 获取年份和月份
        int year = current.get(Calendar.YEAR);
        int month = current.get(Calendar.MONTH) + 1;

        String monthString = month < 10 ? "0" + month : String.valueOf(month);

        // 上传子目录 （ upload/year/month/XX ）
        String subDir = UPLOAD_SUB_DIR + year + FILE_SEPARATOR + monthString + FILE_SEPARATOR;

        // 获取原文件名
        String originalBasename = FileNameUtils.getBasename(Objects.requireNonNull(file.getOriginalFilename()));

        // 重命名文件 （原文件名 - random UUID）
        String basename = originalBasename + '-' + FileNameUtils.randomUuidWithoutDash();

        // 获取扩展名
        String extension = FileNameUtils.getExtension(file.getOriginalFilename());

        // 构建文件路径（ eg：upload/2020/08/test-76c77e42f5b44ab8bff90684916745f8.jpg
        String subFilePath = subDir + basename + '.' + extension;

        // 获取上传路径
        Path uploadPath = Paths.get(workDir, subFilePath);
        try {
            // 构建目录
            Files.createDirectories(uploadPath.getParent());
            Files.createFile(uploadPath);

            // 上传
            file.transferTo(uploadPath.toFile());

            return subFilePath;
        } catch (IOException e) {
            throw new RuntimeException("文件上传错误！", e);
        }
    }

    public String uploadAndDelete(MultipartFile file, String deletePath) {
        String upload = upload(file);
        String path = workDir + deletePath;
        delete(path);
        return upload;
    }

    @Async
    public void delete(String path) {
        File file = new File(path);
        file.deleteOnExit();
    }

}
